package com.SiLa.LispPlugin;

import com.intellij.lexer.FlexLexer;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.TokenType;
import java.util.*;
import java.lang.reflect.Field;
import org.jetbrains.annotations.NotNull;
import static com.SiLa.LispPlugin.psi.LispTypes.*;


%%

%class LispLexer
%implements FlexLexer
%unicode
%public

%function advance
%type IElementType



/***** Custom user code *****/

%{
StringBuffer string = new StringBuffer();
%}




/***** Macros - Regular expressions *****/

LineTerminator=\r|\n|\r\n
InputCharacter=[^\r\n]
WhiteSpace={LineTerminator}|[ \t\f]

LineComment=([ \t\f]*";"{InputCharacter}*{LineTerminator})

BlockComment=(({LineComment})+[ \t\f]*";"{InputCharacter}*)

Digit=[0-9]
IntegerLiteral=(0|([1-9]({Digit})*))

ExponentPart=[Ee]["+""-"]?({Digit})*
FloatingPointLiteral1=({Digit})+"."({Digit})*({ExponentPart})?
FloatingPointLiteral2="."({Digit})+({ExponentPart})?
FloatingPointLiteral3=({Digit})+({ExponentPart})
FloatingPointLiteral4=({Digit})+
FloatLiteral=({FloatingPointLiteral1})|({FloatingPointLiteral2})|({FloatingPointLiteral3})|({FloatingPointLiteral4})

NumericLiteral=["+""-"]?({IntegerLiteral})|({FloatLiteral})

Symbol=[A-Za-z0-9!@#$%<>/?&\^\+\*\-=\.\?:]*

EscapeSequence=\\[^\r\n]
StringLiteral=\"([^\\\"]|{EscapeSequence})*(\"|\\)?


%%

{WhiteSpace} { return WHITESPACE; }
{LineComment} { return COMMENT; }
{BlockComment} { return COMMENT; }
{NumericLiteral} { return NUMBER; }
{StringLiteral} { return STRING; }


"(" { return LEFT_PAREN; }
")" { return RIGHT_PAREN; }

[Tt] { return SYMBOL; }
[Nn][Ii][Ll] { return SYMBOL; }

[Qq][Uu][Oo][Tt][Ee] { return KEYWORDS; }
[Ll][Aa][Mm][Bb][Dd][Aa] { return KEYWORDS; }
[Cc][Oo][Nn][Dd] { return KEYWORDS; }
[Ii][Ff] { return KEYWORDS; }
[Ll][Ee][Tt] { return KEYWORDS; }
[Ww][Hh][Ee][Nn] { return KEYWORDS; }
[Uu][Nn][Ll][Ee][Ss][Ss] { return KEYWORDS; }
[Pp][Rr][Oo][Gg][Nn] { return KEYWORDS; }
[Ss][Ee][Tt][Qq] { return KEYWORDS; }

"`" { return SYMBOL; }
"'" { return SYMBOL; }
"," { return SYMBOL; }
",@" { return SYMBOL; }
"#'" { return SYMBOL; }

[Dd][Ee][Ff][Uu][Nn] { return KEYWORDS; }
[Dd][Ee][Ff][Mm][Aa][Cc][Rr][Oo] { return KEYWORDS; }
[Dd][Ee][Ff][Vv][Aa][Rr] { return KEYWORDS; }
[Dd][Ee][Ff][Cc][Ll][Aa][Ss][Ss] { return KEYWORDS; }
[Dd][Ee][Ff][Mm][Ee][Tt][Hh][Oo][Dd] { return KEYWORDS; }
[Dd][Ee][Ff][Gg][Ee][Nn][Ee][Rr][Ii][Cc] { return KEYWORDS; }
[Dd][Ee][Ff][Pp][Aa][Cc][Kk][Aa][Gg][Ee] { return KEYWORDS; }
[Dd][Ee][Ff][Pp][Aa][Rr][Aa][Mm][Ee][Tt][Ee][Rr] { return KEYWORDS; }
[Dd][Ee][Ff][Cc][Oo][Nn][Ss][Tt][Aa][Nn][Tt] { return KEYWORDS; }

"&"[Aa][Uu][Xx] { return SYMBOL; }
"&"[Bb][Oo][Dd][Yy] { return SYMBOL; }
"&"[Kk][Ee][Yy] { return SYMBOL; }
"&"[Oo][Pp][Tt][Ii][Oo][Nn][Aa][Ll] { return SYMBOL; }
"&"[Rr][Ee][Ss][Tt] { return SYMBOL; }


{Symbol} { return SYMBOL; }


. { return BAD_CHARACTER; }